<?php namespace xlx;

class PrSup extends \xlx\PrActor {

    public static function start_link($class_fn,$opt=['name'=>'','strategy'=>'']){
        if($class_fn instanceof \Closure){
            $class_fn = $class_fn->bindTo(NULL,NULL);
            $class_fn = (serialize(new \Opis\Closure\SerializableClosure($class_fn)) );
        }  
        switch ($opt['strategy']) { 
            default:
                return \xlx\PrActor::spawn_opt([self::class,'onOneForAll'],[$class_fn],[
                    'ip'=> PrService::$reg_addr ,
                    //'link'=>self
                ]);
        }       
    }


    public function onOneForAll($class_fn){
        if (is_string($class_fn) && substr($class_fn, 0, 38)
            =='C:32:"Opis\Closure\SerializableClosure') {
            $class_fn = unserialize($class_fn)->getClosure();
            $class_fn = $class_fn->bindTo($this);
        }
  
        \call_user_func($class_fn);

        while(1){ 

            foreach ($this->childsdesc as $index => $value){ 
                $pid = yield $this->{$value[0]}($value[1]);   
            }  

            $this->trapexit(true);
            $message = yield $this->receive();

            $self = $this->self(); 
            $links = \xlx\PrService::$server_monitor[$self];
            foreach ($links as $coid => $_) {
                yield \xlx\PrActor::unlink($coid);
                \xlx\PrActor::exit($coid,'kill'); 
            }

        }

    }
    public function onOneForZero($conn,$class_fn,$opt){

        
    }
    public function onOneForOne($conn,$class_fn,$opt){ 
        $actor = new PrActor(function()use($class_fn,$opt){ 
            $sup = new \xlx\PrSup();
            \call_user_func($class_fn,$sup,$opt);
 
            foreach ($sup->childsdesc as $index => $value){ 
                $pid = yield $this->{$value['type']}($value['class'],$opt);  
                $this->link( $pid ); 
            }  

            $this->trapexit(true);


        });
        return $actor->coid;
    }




    /** 
     * @param [type] $classOrfunc 启动函数
     * @param [type] $restart 重启方式
     * @param [type] $delay 重启间隔
     * @return void
     */
    public function worker($classOrfunc,$restart=0,$delay=0){ 
        $this->childsdesc[] = [ 'spawn_link', $classOrfunc , [ ] ];
    }

    /** 
     * @param [type] $classOrfunc 启动函数
     * @param [type] $restart 重启方式
     * @param [type] $delay 重启间隔
     * @return void
     */
    public function service($classOrfunc,$restart=0,$delay=0){
        $this->childsdesc[] = ['type'=>\xlx\DbService::class,'class'=>$classOrfunc];
    }
    /** 
     * @param [type] $classOrfunc 启动函数
     * @param [type] $restart 重启方式
     * @param [type] $delay 重启间隔
     * @return void
     */
    public function supervisor($classOrfunc,$restart,$delay){
        
    }
    

}